/*==============================================================================
**                                  Cuong Chu
**                      Proprietary - Copyright (C) 2014
**------------------------------------------------------------------------------
** Supported MCUs      : MCU STM32
** Supported Compilers : KeilC
**------------------------------------------------------------------------------
** File name         : APP_M3_PORTB.c
**  
** Module name       : PORT A
**
** Summary:
**
**= History ===================================================================
** 00.00.01  28/7/2014  Cuong Chu
** - Creation
==============================================================================*/
/******************************************************************************/
/* INCLUSIONS                                                                 */
/******************************************************************************/
#include "comm/comm.h"
#include "bsp/output.h"
#include "tim/timer.h"
/*******************************************************************************/
/* DEFINITION OF CONSTS                                                        */
/*******************************************************************************/
#define PORT_NODE_ID                  0xAABBCC0A
#define HOST_NODE_ID                  0xAABBCCEE
#define COMMUNICATION_PORT            COMM_COM2
/*******************************************************************************/
/* DECLARATION OF LOCAL TYPEDEFS                                               */
/*******************************************************************************/
/* flag start/stop checks cable */
typedef enum
{
  FLG_START_CHECK,
  FLG_STOP_CHECK
}APP_PORT_FlagType;

/* process checking  */
typedef enum
{
  CHK_STARTING,
  CHK_CHECKING,
  CHK_REPORT
}APP_PORT_CableCheckingStateType;
/* client control ID */
typedef enum
{
  SS_MODE_SWITCHING         = 0x11,
  SS_MODE_CABLE_DETECTED    = 0x12,
  SS_MODE_START_CHECK       = 0x13,
  SS_MODE_CHECKING          = 0x14,
  SS_MODE_CABLE_FAILED      = 0x15,
  SS_MODE_CABLE_PASSED      = 0x16,
  SS_MODE_START_DETECT      = 0x17,
  SS_MODE_SET_NBR_WIRES     = 0x18,
  SS_MODE_RESET             = 19
}APP_PORT_CmdFromHostType;
/* action mode */
typedef enum
{
  MODE_AUTO   = 0x01,
  MODE_MANUAL = 0x02
}APP_MAIN_ActionModeType;
/* command  */
typedef struct
{
  APP_PORT_CmdFromHostType      Cmd;
  void                          (*func)(ComM_MessageType* msg);
}APP_PORT_CommandType;
/*******************************************************************************/
/* DECLARATION OF LOCAL FUNCTIONS                                              */
/*******************************************************************************/
/* process command from host  */
static void Port_iResetmd
(
  ComM_MessageType* msg
);
/* process command from host  */
static void Port_iProcessHostCommand
(
  ComM_MessageType* msg
); 
/* process command switching mode  */
static void Port_iCmdSwitchingMode
(
  ComM_MessageType* msg
); 
/* process command from host  */
static void Port_iCmdStartCheck
(
  ComM_MessageType* msg
); 
/* process command from host  */
static void Port_iCmdChecking
(
  ComM_MessageType* msg
); 
/* thread check auto or manual mode */
static void Port_iStartDetect
(
  ComM_MessageType* msg
);

/* thread set nbr of wires to check */
static void Port_iSetCableLenght
(
  ComM_MessageType* msg
);
/*******************************************************************************/
/* DECLARATION OF LOCAL VARIABLES                                              */
/*******************************************************************************/
static const APP_PORT_CommandType    HostCommand[6] = 
{
  {
    SS_MODE_SWITCHING,
    Port_iCmdSwitchingMode
  },
  {
    SS_MODE_START_CHECK,
    Port_iCmdStartCheck
  },
  {
    SS_MODE_CHECKING,
    Port_iCmdChecking
  },
  {
    SS_MODE_START_DETECT,
    Port_iStartDetect
  },
  {
    SS_MODE_SET_NBR_WIRES,
    Port_iSetCableLenght
  },
  {
    SS_MODE_RESET,
    Port_iResetmd
  }
};
/* action mode */
static APP_MAIN_ActionModeType                   ActionMode = MODE_MANUAL;
static APP_PORT_FlagType                         CheckingStatus = FLG_STOP_CHECK;
static uint8_t                                   NbrOfWireToCheck = 0;
/* Rx Message */
static ComM_MessageType                          RxMsg;
/* Tx Message */
static ComM_MessageType                          TxMsg;
/*******************************************************************************/
/* DECLARATION OF LOCAL VARIABLES                                              */
/*******************************************************************************/

/*******************************************************************************
** Function name: main( void  )
** Description  : The main function
** Parameter    : none
** Return value : none
** Remarks      : global variables used, side effects
*******************************************************************************/
int main(void)
{
   OUTPUT_OutputType  i;
   /* init comm */
   ComM_Init(PORT_NODE_ID,COMMUNICATION_PORT);
   /* enabled interrupt request */
   ComM_EnableReceivePort(COMMUNICATION_PORT);
   /* init timer */
   Timer_SystemTickTimerInit();
   /* output clocks supply */
   OUTPUT_IOEnableClock();
   /* init output */
   for(i = OUT_CH_1; i <= OUT_CH_64; i++)
   {
     OUTPUT_OutputInit(i);
     /* set high logic all output */
     OUTPUT_OutputSetLogic(i,STD_HIGH);
   }
// 	 while(1)
// 	 {
// 		 for(j = 0; j < 10;j++)
// 		 {
// 		   for(i = OUT_CH_1; i <= OUT_CH_64; i++)
// 			 {
// 				 /* set high logic all output */
// 				 OUTPUT_OutputSetLogic(i,STD_HIGH);
// 			 }
// 			 
// 			 OUTPUT_OutputSetLogic(j,STD_LOW);
// 			 Timer_DelayMs(1000);
// 		 }
// 	 }
   while(1)
   {
      ComM_MainFunction();  
      /* check incoming message from host */
      if(COMM_OK == ComM_ReadMsgFromQueue(&RxMsg))
      {
        Port_iProcessHostCommand(&RxMsg);
      }
      else
      {
        /* do nothing */
      }
   }
}


/* process command from host  */
static void Port_iResetmd
(
  ComM_MessageType* msg
)
{
      /* global disable irq */
    __disable_irq();
    /* request core reset */
    NVIC_SystemReset();
}

/* process command from host  */
static void Port_iProcessHostCommand
(
  ComM_MessageType* msg
)
{
  uint8_t   LocalCounter = 0;
  /* check valid ID and port */
  if(msg->DstID == PORT_NODE_ID)
  {
    /* check command and execute functional according */
    for( ; LocalCounter < 6 ; LocalCounter++)
    {
      if(HostCommand[LocalCounter].Cmd == msg->MsgID)
      {
        HostCommand[LocalCounter].func(msg);
      }
    }
  }
  else
  {
    /* do nothing */
  }
}
/* process command switching mode  */
static void Port_iCmdSwitchingMode
(
  ComM_MessageType* msg
)
{
  ActionMode = (APP_MAIN_ActionModeType)msg->Data[0];
}
/* process command from host  */
static void Port_iCmdStartCheck
(
  ComM_MessageType* msg
)
{
  OUTPUT_OutputType            i;	
  NbrOfWireToCheck = msg->Data[0];
  CheckingStatus = FLG_START_CHECK;
  for( i = OUT_CH_1;i <= OUT_CH_64;i++)
  {
    OUTPUT_OutputSetLogic(i,STD_HIGH);
  }	
	NbrOfWireToCheck = 0;
}

/* process command from host  */
static void Port_iCmdChecking
(
  ComM_MessageType* msg
)
{
  OUTPUT_OutputType  i;
  for( i = OUT_CH_1;i <= OUT_CH_64;i++)
  {
    OUTPUT_OutputSetLogic(i,STD_HIGH);
  }
  /* set wire to check to low level */
  OUTPUT_OutputSetLogic(msg->Data[0],STD_LOW);
  NbrOfWireToCheck++;
	
}
/* thread check auto or manual mode */
static void Port_iStartDetect
(
  ComM_MessageType* msg
)
{
  OUTPUT_OutputType  i,j;
	j = (OUTPUT_OutputType)msg->Data[0];
  for(i = OUT_CH_1 ; i < j && i <= OUT_CH_64  ;i++)
  {
    OUTPUT_OutputSetLogic(i,STD_LOW);
  }
}

/* thread set nbr of wires to check */
static void Port_iSetCableLenght
(
  ComM_MessageType* msg
)
{
  NbrOfWireToCheck = msg->Data[0];
}

